package com.dxt.controller;

import com.dxt.pojo.Company;
import com.dxt.pojo.Delivery;
import com.dxt.pojo.User;
import com.dxt.service.CompanyService;
import com.dxt.service.CompanyServiceImpl;
import com.dxt.service.DeliveryService;
import com.dxt.service.DeliveryServiceImpl;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.SneakyThrows;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * BelongProject: deliveryManage
 * BelongPackage: com.dxt.controller
 * Description:
 *
 * @Author 段鑫涛
 * @Create 2025/3/30 23:30
 * @Version 1.0
 */
@WebServlet("/delivery/getList")
public class ShowDeliveryListController extends HttpServlet {
    private DeliveryService deliveryService = new DeliveryServiceImpl();
    private CompanyService companyService = new CompanyServiceImpl();
    @Override
    @SneakyThrows
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        User user = (User)session.getAttribute("user");
        Integer id = user.getId();

        List<Delivery> deliveryList = deliveryService.getDeliveryListByUserId(id);
        List<Company> companyList = companyService.getCompanyList();

        /**
         * 把快递公司对象列表整理成map，为了后期根据快递公司id快速获取到对应的快递公司对象
         * stream() 是 List 接口的一个方法，它会把列表转换为一个流（Stream）。流是 Java 8 引入的新特性，能让你以声明式的方式处理集合元素。
         * collect() 是流的一个终端操作，其作用是把流中的元素收集到一个容器里，例如 List、Set 或者 Map。
         * Collectors.toMap() 是 Collectors 工具类提供的一个静态方法，用于把流中的元素收集到一个 Map 中。
         * Company::getId 这是一个方法引用，其作用是指定 Map 的键。Company::getId 表示取 Company 对象的 id 属性作为 Map 的键。
         * company -> company 这是一个 Lambda 表达式，用来指定 Map 的值。company -> company 表示把 Company 对象本身作为 Map 的值。
         */
        Map<Integer, Company> map = companyList.stream().collect(Collectors.toMap(Company::getId, company -> company));

        /**
         * delivery -> delivery.setCompany(map.get(delivery.getCompanyId())) 是一个 Lambda 表达式，它定义了要对集合中的每个 delivery 对象执行的操作。
         * delivery 是集合中的每个元素，代表一个 delivery 对象。
         * delivery.getCompanyId()：调用 delivery 对象的 getCompanyId() 方法，获取该 delivery 对象关联的公司的 id。
         * map.get(delivery.getCompanyId())：使用获取到的 companyId 作为键，从 map 中查找对应的 Company 对象。这里的 map 应该是一个 Map<Integer, Company> 类型的映射，键是公司的 id，值是对应的 Company 对象。
         * delivery.setCompany(...)：调用 delivery 对象的 setCompany() 方法，将从 map 中查找到的 Company 对象设置到 delivery 对象中。
         * 1、使用根据userId查询到的deliveryList集合进行便利
         * 2、要保证 Delivery 类包含 setCompany 方法，并且添加一个 Company 类型的属性（在delivery类中创建一个Company类型的company）：
         */
        deliveryList.forEach(delivery -> delivery.setCompany(map.get(delivery.getCompanyId())));

        req.setAttribute("deliveryList", deliveryList);


        req.getRequestDispatcher("/list.jsp").forward(req, resp);
    }
}
